
using BasicModuleWebApiJWTAuthorization.DBContextx;
using BasicModuleWebApiJWTAuthorization.Helper;
using BasicModuleWebApiJWTAuthorization.Model;
using BasicModuleWebApiJWTAuthorization.PermissionAuthorization;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.IdentityModel.Tokens;
using System.Text;

namespace BasicModuleWebApiJWTAuthorization
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.

            builder.Services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen(); 

            //注册自定义上下文类 
            builder.Services.AddDbContext<MysqlDBContext>(option =>
            {
                option.UseMySql("Server=192.168.211.129;Port=3306;Database=Jwt;Uid=root;Pwd=123456;", new MySqlServerVersion("5.7.20"));
            }, ServiceLifetime.Singleton);
            builder.Services.AddControllersWithViews();
            //配置jwt认证
            builder.Services.AddAuthentication(optin => 
            {
                //配置jwt认证方案
                var deault = optin.DefaultAuthenticateScheme;
                optin.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                var defalut = optin.DefaultChallengeScheme;
                optin.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(option => {
                //配置token认证方式  设置哪些字段为true 代表验证哪些字段
                option.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
                {
                    ValidateIssuer = true, //认证签发者 。生产token系统
                    ValidateAudience = true,//认证受用者 erp系统
                    ValidateLifetime = true,//认证生成token时间
                    ValidateIssuerSigningKey= true,
                    ValidIssuer = "jwt", //认证签发者 。生产token系统
                    ValidAudience = "BasicModuleWebApiJWTAuthorization", //认证受用者 erp系统
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("R2XMnd6TQdYRUmR0cCfL9fk651Fb3kDI")) //认证生成token密钥
                };
            });
            //注册授权处理器
            builder.Services.AddSingleton<IAuthorizationHandler, UserPermissionAuthodrizationHandler>();
            //配置授授权策略
            List<PermissionDefine> permissionDefines = PermissionDefineProvider.GetPermissionDefine();
            builder.Services.AddAuthorization(option => 
            {
                IServiceProvider serviceProvider = builder.Services.BuildServiceProvider();
                MysqlDBContext mysqlDBContext = serviceProvider.GetRequiredService<MysqlDBContext>();
                foreach (var item in permissionDefines) 
                {
                    ////使用自定义授权策略
                    option.AddPolicy(item.PermissionName , x => 
                    {
                        ////添加自定义声明
                        x.AddRequirements(new UserPermissionAuthorizationRequirement(item.PermissionName));
                    });
                    //将策略自定义策略添加到数据库
                    Permission permission = new Permission();
                    permission.PermissionName = item.PermissionName;
                    permission.PermissionType = item.PermissionType;
                    permission.PermissionValue = item.PermissionValue;
                    var data = mysqlDBContext.Permissions.Where(x => x.PermissionName == item.PermissionName && x.PermissionType == item.PermissionType).FirstOrDefault();
                    if (data == null)
                        mysqlDBContext.Add(permission);
                }
                mysqlDBContext.SaveChanges();
            });

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }
            app.Use(next =>
            {
                return async x =>
                {
                    bool? bl = x.User.Identity.IsAuthenticated;
                    var path = x.Request.Path.Value;
                    // 2、给下一个中间件
                    await next(x);
                    //x.Response.StatusCode = 401; //如果授权失败 可以通过中间件修改状态码
                };
            });
            //使用jwt身份验证中间件  
            app.UseAuthentication();
            app.Use(next =>
            {
                return async x =>
                {
                    bool? bl = x.User.Identity.IsAuthenticated;
                    var path = x.Request.Path.Value;
                    // 2、给下一个中间件
                    await next(x);
                };
            });
            //鉴权
            app.UseAuthorization();
            app.Use(next =>
            {
                return async x =>
                {
                    bool bl = x.User.Identity.IsAuthenticated;
                    var path = x.Request.Path.Value;
                    // 2、给下一个中间件
                    await next(x);
                };
            });

            //GenerateKey.Run();
            app.MapControllers();
            //添加mvc路由
            app.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{Id?}", defaults: new { });

            app.Run();
        }
    }
}
